package Code.Objects.Characters.Player.GUI;

import org.jrabbit.base.core.types.Updateable;
import org.jrabbit.base.data.structures.UpdateList;
import org.jrabbit.base.graphics.image.Image;
import org.jrabbit.base.graphics.transforms.Vector2d;
import org.jrabbit.base.managers.ResourceManager;
import org.jrabbit.base.managers.window.WindowManager;
import org.jrabbit.standard.game.graphics.skins.image.ImageSkin;
import org.jrabbit.standard.game.objects.Sprite;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Color;

import Code.Basic.Entity.GenericCharacter;
import Code.Objects.Characters.Player.Player;

public class Radar extends Sprite implements Updateable
{
	private Sprite radarFrame;

	private Sprite radarPulse;
	private int pulseDuration = 20000;
	private int pulseInterval = 10000;
	private int pulseTimer = pulseDuration - pulseInterval;

	private ImageSkin radarPing;
	private ImageSkin playerMark;

	private UpdateList<Ping> pings;
	private int pingTimer = 0;
	private int pingDuration = 500;
	private Color[] colors;

	private final static double PULSE_RADIUS = WindowManager.getDisplayDiagonal() * 1.5;
	private final static double RADAR_RADIUS = 64;
	private final static double DISPLAY_MULT = PULSE_RADIUS / RADAR_RADIUS;

	private Player player;

	public Radar(Player p)
	{
		super("Resources/Images/GUI/Game/Radar/Radar Back.png");
		useScreenCoords(true);
		location.set(WindowManager.getDisplayWidth() - getScaledWidth() / 2, 
				WindowManager.getDisplayHeight() - getScaledHeight() / 2);

		radarFrame = new Sprite("Resources/Images/GUI/Game/Radar/Radar Frame.png");
		radarFrame.useScreenCoords(true);
		radarFrame.location().set(location);

		radarPulse = new Sprite("Resources/Images/GUI/Game/Radar/Pulse.png");
		radarPulse.useScreenCoords(true);
		radarPulse.location().set(location);
		radarPulse.location().add(7, 7);
		radarPulse.scalar().set(0.05f);
		radarPulse.color().set(1f, 0, 0);

		radarPing = new ImageSkin("Resources/Images/GUI/Game/Radar/Radar Mark.png");
		playerMark = new ImageSkin("Resources/Images/GUI/Game/Radar/Player Mark.png");

		pings = new UpdateList<Ping>();
		colors = new Color[] {Color.blue, new Color(0.5f, 1f, 0), Color.red, Color.white};

		player = p;
	}
	
	public void update(int delta)
	{
		if(player != null)
		{
			pingTimer += delta;
			if(pingTimer > pingDuration)
			{
				pingTimer -= pingDuration;
				checkRadar(player);
			}

			pulseTimer += delta;
			if(pulseTimer >= pulseDuration)
			{
				pulseTimer -= pulseDuration + pulseInterval;
			}
			if(pulseTimer > 0)
			{
				radarPulse.scalar().set(2.5f * pulseTimer / pulseDuration);
				radarPulse.rotation().set(ResourceManager.random().nextDouble() * 360);
				radarPulse.color().setAlpha(1f - (float) Math.sqrt(pulseTimer * 1.0f / pulseDuration));
			}
			else
			{
				radarPulse.color().setAlpha(0);
			}
		}
	}

	public void checkRadar(Player player)
	{
		pings.clear();
		UpdateList<GenericCharacter> characters = player.getWorld().getCharacters();

		for(GenericCharacter c:characters)
		{
			if (c != player)
			{
				Vector2d diff = c.location().difference(player.location());
				if (diff.magnitude() <= PULSE_RADIUS)
				{
					diff.divide(DISPLAY_MULT);
					pings.add(new Ping(diff, c.getFaction()));
				}
			}
		}
	}

	public void render()
	{
		super.render();
		radarPulse.render();
		radarFrame.render();
	}

	public void draw()
	{
		super.draw();
		GL11.glTranslated(7, 7, 0);
		Image pingMark = radarPing.object();
		if (pings != null)
		{
			int fac = -1;
			for (Ping p : pings)
			{
				if(fac != p.faction)
				{
					fac = p.faction;
					colors[fac].bind();
				}
				p.location.bind();
				pingMark.render();
				p.location.release();
			}
		}
		playerMark.render();
	}

	private class Ping
	{
		private Vector2d location;
		public int faction;

		public Ping(Vector2d loc, int fac)
		{
			location = loc;
			faction = fac;
		}
	}
}